#ifndef SEQUENCELIST_C
#define SEQUENCELIST_C

#include "SequenceList.h"

Status InitList_Sq(SqList *L)
{
    (*L).elem = (LElemType_Sq *)malloc(LIST_INIT_SIZE * sizeof(LElemType_Sq));
    if ((*L).elem == NULL) {
        exit(OVERFLOW);
    }
    (*L).length = 0;
    (*L).listsize = LIST_INIT_SIZE;
    return OK;
}

void ClearList_Sq(SqList *L)
{
    (*L).length = 0;
}

void DestroyList_Sq(SqList *L)
{
    free(L->elem);
    L->elem = NULL;
    L->length = 0;
    L->listsize = 0;
}

Status ListEmpty_Sq(SqList L)
{
    return (L.length == 0 ? TRUE : FALSE);
}

int ListLength_Sq(SqList L)
{
    return L.length;
}

Status GetElem_Sq(SqList L, int i, LElemType_Sq *e)
{
    if (i < 1 || i > L.length) {
        return ERROR;
    }
    *e = L.elem[i - 1];
    return OK;
}

int LocateElem_Sq(SqList L, LElemType_Sq e, Status(Compare)(LElemType_Sq, LElemType_Sq))
{
    int i = 0;
    while (i < L.length && !Compare(e, L.elem[i])) {
        ++i;
    }
    if (i<L.length)
        return i + 1;
    return 0;
}

Status PriorElem_Sq(SqList L, LElemType_Sq cur_e, LElemType_Sq *prior_e)
{
    int i;
    if (L.elem[0] != cur_e) {
        i = 1;
        while (i < L.length && L.elem[i] != cur_e) {
            ++i;
        }
        if (i < L.length) {
            *prior_e = L.elem[i - 1];
            return OK;
        }
    }
    return ERROR;
}

Status NextElem_Sq(SqList L, LElemType_Sq cur_e, LElemType_Sq *next_e)
{
    int i = 0;
    while (i < L.length-1 && L.elem[i] != cur_e) {
        ++i;
    }
    if (i < L.length-1){
        *next_e = L.elem[i + 1];
        return OK;
    }
    return ERROR;
}

Status ListInsert_Sq(SqList *L, int i, LElemType_Sq e)
{
    LElemType_Sq *newbase;
    LElemType_Sq *p, *q;
    if (i < 1 || i > L->length + 1) {
        return ERROR;
    }
    if (L->length >= L->listsize){
        newbase = (LElemType_Sq *)realloc(L->elem, (L->listsize + LISTINCREMENT) * sizeof(LElemType_Sq));
        if (!newbase)
            exit(OVERFLOW);
        L->elem = newbase;
        L->listsize += LISTINCREMENT;
    }
    q = &L->elem[i - 1];
    for (p = &L->elem[L->length - 1]; p >= q; --p){
        *(p + 1) = *p;
    }
    *q = e;
    ++L->length;
    return OK;
}

Status ListDelete_Sq(SqList *L, int i, LElemType_Sq *e)
{
    if (i < 1 || i > L->length)
        return ERROR;
    LElemType_Sq *p, *q;
    p = &L->elem[i - 1];
    *e = *p;
    q = L->elem + L->length - 1;
    for (++p; p <= q; ++p)
        *(p - 1) = *p;
    --L->length;
    return OK;
}

Status ListTraverse_Sq(SqList L, void(Visit)(LElemType_Sq))
{
    for (int i = 0; i < L.length; ++i) {
        Visit(L.elem[i]);
    }
    return OK;
}

#endif
